/*
 * Documentos.cpp
 *
 *  Created on: 15/10/2011
 *      Author: diego
 */

#include "Documentos.h"

Documentos::Documentos() {
	/*
	Registro fijo
	+--------------+---------------+-------+---------------+
	| id_documento |  offset_path  | largo | cant_terminos |
	+--------------+---------------+-------+---------------+
	*/
	Configuracion* conf = Configuracion::getConf(PATH_CONF);

	this->pathRegFijo = conf->path_documentos() + "reg_fijos.dat";
	this->pathRegVariable = conf->path_documentos() + "reg_variables.dat";

	this->ultimoID = 0;
	this->cantDocs = 0;

	this->lista = new Lista<nodo_doc>();

	ifstream fd_rf(this->pathRegFijo.c_str(), ios::in | ios::binary);
	fd_rf.seekg(0, ios::beg);
	nodo_doc nodo;

	if (fd_rf.good()){
		fd_rf.read(reinterpret_cast<char *>(&nodo), sizeof(nodo_doc));
		while (!fd_rf.eof()){
			this->ultimoID = nodo.doc_id;
			this->lista->agregar(nodo);
			cantDocs++;
			fd_rf.read(reinterpret_cast<char *>(&nodo), sizeof(nodo_doc));
		}
	}

	fd_rf.close();
}

void Documentos::agregarDocumentos(string path, int cant_terminos){
	ofstream fd_rf(this->pathRegFijo.c_str(), ios::app | ios::binary);
	ofstream fd_rv(this->pathRegVariable.c_str(), ios::app | ios::binary);

	this->ultimoID++;
	cant_terminos++;
	int nuevo_id = this->ultimoID;

	nodo_doc nuevo_nodo;
	nuevo_nodo.doc_id = nuevo_id;
	nuevo_nodo.offset = fd_rv.tellp();
	nuevo_nodo.largo = path.length();
	nuevo_nodo.cant_terminos = cant_terminos;

	fd_rf.write(reinterpret_cast<char *>(&nuevo_nodo),sizeof(nodo_doc));

	fd_rv.write(path.c_str(), path.length());

	fd_rf.close();
	fd_rv.close();

	this->lista->agregar(nuevo_nodo);
	return;
}

void Documentos::printLista(){
	IteradorLista<nodo_doc> it = this->lista->iterador();
	nodo_doc nodo;
	while (it.tieneSiguiente()){
		nodo = it.siguiente();
		cout << "id: " << nodo.doc_id << " -- offset: " << nodo.offset << " -- largo: " << nodo.largo << endl;
	}
}

int Documentos::getUltimoId(){
	return this->ultimoID + 1;
}

string Documentos::getPath(int id){
	IteradorLista<nodo_doc> it = this->lista->iterador();

	nodo_doc nodo;
	bool salida = false;
	while(it.tieneSiguiente() && salida == false){
		nodo = it.siguiente();
		salida = nodo.doc_id == id;
	}

	if (salida == false){
		return "";
	}

	ifstream fd_rf(this->pathRegVariable.c_str(), ios::in | ios::binary);
	fd_rf.seekg(nodo.offset, ios::beg);

	char buffer[nodo.largo];
	fd_rf.read(buffer, nodo.largo);

	string s(buffer);

	return s;
}

int Documentos::getCantTerminos(int id){
	IteradorLista<nodo_doc> it = this->lista->iterador();

	nodo_doc nodo;
	while(it.tieneSiguiente()){
		nodo = it.siguiente();
		if (nodo.doc_id == id){
			return nodo.cant_terminos;
		}
	}

	return -1;
}

size_t Documentos::getCantDocs() const
{
    return cantDocs;
}

Documentos::~Documentos() {
	delete this->lista;
}

